#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <functional>
#include <vector>

// 自定义处理信号

// void handler(int signum) // 这个参数会自动传signal(SIGINT, handler)的 SIGINT
// {
//     std::cout << "获得了一个信号 , " << signum << std::endl;
// }

// int main()
// {
//     // typedef void (*sighandler_t)(int); 函数的类型必须是 void(int)
//     // sighandler_t signal(int signum, sighandler_t handler);
//     signal(SIGINT, handler);

//     while (true)
//     {
//         std::cout << "我是一个进程 !" << std::endl;
//         sleep(1);
//     }

//     return 0;
// }

//// 验证无法被捕捉的信号

// 自定义捕捉
// void headler(int sig)
// {
//     std::cout << "我是信号 : " << sig << std::endl;
// }

// int main()
// {
//     // 信号一共 31 个 , 是我们需要了解的信号
//     // 自定义捕捉 31 个信号 , 看哪个信号不能被捕捉 , 找到一个就排除一个
//     for (int i = 1; i <= 31; ++i)
//     {
//         signal(i, headler); // 自定义捕捉
//     }

//     for (int i = 1; i <= 31; ++i)
//     {
//         if (i == 9 || i == 19)
//             continue;
//         sleep(1); // 每隔 1 s 给自己发一个信号 , 然后去自定义捕捉信号
//         raise(i); // 进程自己给自己发信号 , 进行信号的捕捉
//     }

//     // while (true)
//     // {
//     //     std::cout << " 我是一个进程 : " << getpid() << std::endl;
//     //     sleep(1);
//     // }
//     return 0;
// }

//////////  系统调用 -- alarm -- 闹钟 


// //自定义捕捉 
// void handler(int sig)
// {
//     std::cout << "收到信号 : " << sig << std::endl;
//     //exit(1); // 默认是终止进程
//     alarm(1); // 让闹钟重复响 , 因为每隔 1 s 会发送信号 , 然后 SIGALRM 就会自定义捕捉就会进入这里 
// }
// // 闹钟的作用 : 隔设定的时间后向进程发送一个信号 : SIGALRM , 默认终止进程
// int main()
// {
//     signal(SIGALRM ,handler);    

//     alarm(1);
//     int cnt = 0;
//     // while(true)
//     // {
//     //     //std::cout << "我是进程 :  ,  " << getpid() << "cnt = " << cnt ++ << std::endl;
//     //     std::cout << "." << std::endl;
//     //     sleep(1);
//     // }

//     return 0;
// }


//////////////////////////////  操作系统的本质 !!! --- 死循环  !!!!!!!!!!

//包装器 , 里面是函数指针
// using Task = std::function<void()>;

// std::vector<Task> tasks; // 里面都是一个一个的任务 


// void Load()
// {
//     std::cout << "这是一个加载的任务" << std::endl;
// }
// void UpLoad()
// {
//     std::cout << "这是一个上传的任务" << std::endl;
// }

// //自定义捕捉 
// void handler(int sig)
// {
//     //执行 -- 调用包装器
//     std::cout << "##########################" << std::endl;
//     for(auto& task : tasks)
//     {
//         task();
//     }
//     std::cout << "##########################" << std::endl;

//     alarm(1); // 让闹钟重复响 , 因为每隔 1 s 会发送信号 , 然后 SIGALRM 就会自定义捕捉就会进入这里 
// }

// int main()
// {

//     //注册任务
//     tasks.emplace_back(Load);
//     tasks.emplace_back(UpLoad);


//     signal(SIGALRM ,handler);    

//     alarm(1);
    
//     //意思是一直暂停 , 只有收到闹钟刺激时才执行对于任务 
//     while(true)
//     {   
//         //pause() 这是一个系统调用 , 用来暂停进程的 !
//         pause();
//     }

//     return 0;
// }


////////////////////  硬件异常产生信号 !

//自定义捕捉信号 
void healder(int sig)
{
    std::cout << "我是一个信号 : " << sig << std::endl;
    exit(1);
}

int main()
{
    std::cout << "我是一个进程 !" << std::endl;
    std::cout << "我是一个进程 !" << std::endl;
    std::cout << "我是一个进程 !" << std::endl;

    //这里看看, 除0 错误会发信号 ???? 
    for(int i = 1; i < 32; ++i)
    {
        signal(i , healder);
    }
    //这里触发一个除0错误 !
    // int a = 10;
    // a = a/0;
    
    int* ptr = nullptr; // 空指针 , 没有任何指向
    *ptr = 100; // 对空指针赋值 , 这就是野指针 
    

    std::cout << "我是一个进程 !" << std::endl;

    return 0;
}